package cz.cuni.amis.episodic.bayes.utils;

import cz.cuni.amis.episodic.bayes.utils.chart.AreaChart;
import cz.cuni.amis.episodic.bayes.utils.chart.GraphPaintingDevice;
import cz.cuni.amis.episodic.dybanem.DBN;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Stroke;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.Range;

/**
 *
 * @author ik
 */
public class MemoryChartCreator {

    /**
     * Creates various graphs that can be extracted from the DynamicNodeProperty
     * through the time.
     *
     * @param nodeEvolutionList
     */
    public static void createDefaultCharts(List<DynamicNodeProperty[]> nodeEvolutionList, DBN net, GraphPaintingDevice graphDevice) throws Exception {
        for (int j = 0; j < nodeEvolutionList.get(0).length; j++) {
            List<DynamicNodeProperty> list = new ArrayList<>();
            for (int i = 0; i < nodeEvolutionList.size(); i++) {
                list.add(nodeEvolutionList.get(i)[j]);
            }
            createChartsForOneNode(list, net, graphDevice);
        }
    }

    /**
     * Marks time of the observation.
     * @param time
     * @param chart
     */
    public static JFreeChart addTimeMarker(int time, JFreeChart chart) {
        XYPlot plot = chart.getXYPlot();
    	ValueMarker marker = new ValueMarker(time);
        marker.setPaint(Color.black);
        marker.setStroke(new BasicStroke(4f));
        plot.addDomainMarker(marker);
        return chart;
    }
    
    /**
     * Draws charts that show evolution of beliefs in one node over multiple time steps.
     * Charts are: posterior probability, entropy and surprise.
     * @param nodeEvolutionList list of beliefs in one node
     * @param net
     * @param graphDevice
     * @throws IOException
     * @throws Exception
     */
    public static void createChartsForOneNode(List<DynamicNodeProperty> nodeEvolutionList, DBN net, GraphPaintingDevice graphDevice) throws IOException, Exception {

        for (int i = 0; i < nodeEvolutionList.size(); i++) {
            DynamicNodeProperty nodeProp = nodeEvolutionList.get(i);
            
            graphDevice.outputGraph(
            		addTimeMarker(i, 
                    MemChart.chartXYBlockTimeValue(nodeProp.getFullPosterior(), net.getNet().getOutcomeIds(nodeProp.getNode()))),
                    nodeProp.getNode() + "_posterior", i);

            graphDevice.outputGraph(
            		addTimeMarker(i,
                    AreaChart.chart(nodeProp.getEntropy(), Color.green, null, "Entropy")),
                    nodeProp.getNode() + "_entropy", i);
            graphDevice.outputGraph(
            		addTimeMarker(i,
                    AreaChart.chart(nodeProp.getSurprise(), Color.yellow, new Range(0, 10), "Surprise")),
                    nodeProp.getNode() + "_surprise", i);
        }

        // draw surprise evolution through time
        double[] surprise = new double[nodeEvolutionList.size()];
        for (int i = 0; i < surprise.length; i++) {
            surprise[i] = nodeEvolutionList.get(i).getSurprise()[i];
        }
        graphDevice.outputGraph(
                AreaChart.chart(surprise, Color.green, null, "Overall surprise"),
                nodeEvolutionList.get(0).getNode() + "_surprise_all");
    }
}
